package com.iraeta.service.basic.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.iraeta.common.ServiceException;
import com.iraeta.dao.main.ErpCsSnapshotCangkuDao;
import com.iraeta.dao.main.PlanDao;
import com.iraeta.dao.main.PlancangkuDao;
import com.iraeta.entity.main.ErpCsSnapshotCangku;
import com.iraeta.entity.main.Plan;
import com.iraeta.entity.main.Plancangku;
import com.iraeta.entity.main.type.PlanPdlx;
import com.iraeta.entity.main.type.PlanStatus;
import com.iraeta.entity.main.type.PlanYwlx;
import com.iraeta.entity.main.type.PlanZq;
import com.iraeta.entity.main.vo.PlanVo;
import com.iraeta.service.basic.PlanService;
import com.iraeta.service.sys.impl.WeiXinService;
import com.iraeta.uitl.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class PlanServiceImpl implements PlanService {
    private static final Logger logger = LoggerFactory.getLogger(PlanServiceImpl.class);

    @Autowired
    PlanDao planDao;
    @Autowired
    PlancangkuDao plancangkuDao;
    @Autowired
    ErpCsSnapshotCangkuDao erpCsSnapshotCangkuDao;
    @Autowired
    WeiXinService weiXinService;

    @Override
    public List<PlanVo> pagePlan(String title) {
        List<Plan> planList = planDao.pagePlan(title);
        List<PlanVo> planVoList = new ArrayList<>();
        for (Plan plan : planList) {
            PlanVo planVo = planToVo(plan);
            planVoList.add(planVo);
        }
        return planVoList;
    }

    @Override
    public List<PlanVo> PageSelfPlan(String title, Integer userId) {
        List<Plan> planList = planDao.listUserSelfPlan(title, PlanStatus.submit, userId);
        List<PlanVo> planVoList = new ArrayList<>();
        for (Plan plan : planList) {
            PlanVo planVo = planToVo(plan);
            planVoList.add(planVo);
        }
        return planVoList;
    }

    private PlanVo planToVo(Plan plan){
        PlanVo planVo = new PlanVo();
        BeanUtil.copyProperties(plan, planVo, true);
        planVo.setStatusName(PlanStatus.getStatusName(plan.getStatusid()));
        planVo.setPdlxName(PlanPdlx.getPlanPdlxName(plan.getPdlx()));
        planVo.setYwlxName(PlanYwlx.getPlanYwlxName(plan.getYwlx()));
        planVo.setZqName(PlanZq.getPlanZqName(plan.getZq()));
        return planVo;
    }

    @Override
    public Plan getPlan(Integer planId) {
        return planDao.selectByPrimaryKey(planId);
    }
    @Override
    public List<HashMap<String, Object>> getPlanCangKu(Integer planId){
        return plancangkuDao.selectByPlanId(planId);
    }

    @Transactional
    @Override
    public void addPlan(Plan plan, JSONArray cangKuJSONArray) {
        planDao.insert(plan);
        for(int i =0;i<cangKuJSONArray.size();i++){
            Integer cangKuId = cangKuJSONArray.getInteger(i);
            Plancangku plancangku = new Plancangku(plan.getId(), cangKuId);
            plancangkuDao.insert(plancangku);
        }
    }

    @Transactional
    @Override
    public void updatePlan(Plan plan, JSONArray cangKuJSONArray) {
        planDao.updateByPrimaryKey(plan);
        List<Integer> cangKuIds = new ArrayList<>();
        for(int i =0; i<cangKuJSONArray.size(); i++){
            cangKuIds.add(cangKuJSONArray.getIntValue(i));
        }
        for (Integer cangkuId : cangKuIds) {
            if(plancangkuDao.selectByCkIdAndPlanId(plan.getId(), cangkuId) == null){
                Plancangku plancangku = new Plancangku(plan.getId(), cangkuId);
                plancangkuDao.insert(plancangku);
            }
        }
        String cangKuIdStr = Util.parseListToString(cangKuIds);
        plancangkuDao.deletePlanCangKuIdStr(plan.getId(), cangKuIdStr);
    }

    @Transactional
    @Override
    public void deletePlan(Integer planId) {
        planDao.deleteByPrimaryKey(planId);
        plancangkuDao.deleteByPlanId(planId);
    }

    @Transactional
    @Override
    public void faBuPlan(Integer planId) {
        Plan plan = planDao.selectByPrimaryKey(planId);
        List<String> wxuserIds = plancangkuDao.selectPlanCangKuUsers(plan.getId());
        Set<String> wxUserSet = new HashSet<>(wxuserIds);
        String toUser = "";
        for (String s : wxUserSet) {
            toUser += s + "|";
        }
        toUser = toUser.substring(0, toUser.length() - 1);
        String content = plan.getCreateuser() + "发布了盘点计划[" + plan.getTitle() + "]，请登录系统查看";
        String msg = weiXinService.setWxUserTextMessage(toUser, content);
        if(!StrUtil.isEmpty(msg)){
            throw new ServiceException(msg);
        }
        planDao.updateStatus(planId, PlanStatus.submit);
    }

    @Override
    public List<Plan> listSelfPlan(Integer userId) {
        return planDao.listUserSelfPlan(null, PlanStatus.submit, userId);
    }

    /*统计用*/
    @Override
    public List<HashMap<String, Object>> getPlanCangKuOnce(Integer planId) {
        Plan plan = planDao.selectByPrimaryKey(planId);
        List<HashMap<String, Object>> res = plancangkuDao.selectByPlanId(planId);
        for (HashMap<String, Object> planCangKuMap : res) {
            int cangKuId = (Integer) planCangKuMap.get("cangKuId");
            ErpCsSnapshotCangku erpCsSnapshotCangku = erpCsSnapshotCangkuDao.selectByPlanAndCangKuId(planId, cangKuId);
            if(erpCsSnapshotCangku == null){
                planCangKuMap.put("tbStatus", 0);
            }else{
                planCangKuMap.put("tbStatus", 1);
                planCangKuMap.put("hgStatus", 0);
                planCangKuMap.put("chouchalv", erpCsSnapshotCangku.getChouchalv());
                if(plan.getPdlx() == PlanPdlx.quanbu){
                    if(erpCsSnapshotCangku.getChouchalv().compareTo(new BigDecimal("100")) == 0){       //如果是全检， 则要达到100%
                        planCangKuMap.put("hgStatus", 1);
                    }
                }else{
                    if(erpCsSnapshotCangku.getChouchalv().compareTo( new BigDecimal(plan.getCdefine4())) >= 0){     //如果是抽检， 则要达到抽检率  并且重复率小于指定数据 (一次性不存在这个问题)
                        planCangKuMap.put("hgStatus", 1);
                    }
                }
            }
        }
        return res;
    }

    @Override
    public List<HashMap<String, Object>> getPlanCangKuZq(Integer planId, Date startDate, Date endDate) {
        Plan plan = planDao.selectByPrimaryKey(planId);
        List<HashMap<String, Object>> res = plancangkuDao.selectByPlanId(planId);
        for (HashMap<String, Object> planCangKuMap : res) {
            int cangKuId = (Integer) planCangKuMap.get("cangKuId");
            ErpCsSnapshotCangku erpCsSnapshotCangku = erpCsSnapshotCangkuDao.selectByPlanAndCangKuId2(planId, cangKuId, DateUtil.formatDate(startDate), DateUtil.formatDate(endDate) );
            if(erpCsSnapshotCangku == null){
                planCangKuMap.put("tbStatus", 0);
            }else{
                planCangKuMap.put("tbStatus", 1);
                planCangKuMap.put("hgStatus", 0);
                planCangKuMap.put("chouchalv", erpCsSnapshotCangku.getChouchalv());
                planCangKuMap.put("chongfulv", erpCsSnapshotCangku.getChongfulv());
                if(plan.getPdlx() == PlanPdlx.quanbu){
                    if(erpCsSnapshotCangku.getChouchalv().compareTo(new BigDecimal("100")) == 0){       //如果是全检， 则要达到100%
                        planCangKuMap.put("hgStatus", 1);
                    }
                }else{
                    if(erpCsSnapshotCangku.getChouchalv().compareTo( new BigDecimal(plan.getCdefine4())) >= 0){     //如果是抽检， 则要达到抽检率  并且重复率小于指定数据
                        if(erpCsSnapshotCangku.getChongfulv().compareTo(new BigDecimal(plan.getCdefine5())) <= 0){
                            planCangKuMap.put("hgStatus", 1);
                        }
                    }
                }
            }
        }
        return res;
    }

    /*定时任务函数*/
    /*根据周期和截止日期， 自动关闭盘点计划*/
    @Override
    public void updatePlanStatus() {
        Date now = new Date();
        List<Plan> planList = planDao.listPlanByStatus(PlanStatus.submit);
        for (Plan plan : planList) {
            if(plan.getZq() == PlanZq.once){
                Date jieZhiRiQi = DateUtil.parseDate(plan.getCdefine2());
                if(DateUtil.compare(now, jieZhiRiQi) > 0){
                    planDao.updateStatus(plan.getId(), PlanStatus.stop);
                }
            }
        }
    }

    @Override
    public void planRemind() {
        List<Plan> planList = planDao.listPlanByStatus(PlanStatus.submit);
        for (Plan plan : planList) {
            try {
                Date beginJcDate = null;
                Date today = DateUtil.parseDate( DateUtil.today());
                Date nextDay = DateUtil.offsetDay(today, 1);
                int year = DateUtil.year(today);
                int month = DateUtil.month(today) + 1;
                int quarter = DateUtil.quarter(today); //第几季度
                if(plan.getZq() == PlanZq.month){
                    beginJcDate = DateUtil.parseDate(year + "-" + month + "-" + plan.getCdefine1());
                } else if (plan.getZq() == PlanZq.jidu) {
                    int calcMonth = (quarter - 1) * 3 + Integer.parseInt(plan.getCdefine3());
                    beginJcDate = DateUtil.parseDate(year + "-" + calcMonth + "-" + plan.getCdefine1());
                }else {
                    continue;
                }
                if(beginJcDate.getTime() >= today.getTime() && beginJcDate.getTime() < nextDay.getTime()){
                    List<String> wxuserIds = plancangkuDao.selectPlanCangKuUsers(plan.getId());
                    Set<String> wxUserSet = new HashSet<>(wxuserIds);
                    String toUser = "";
                    for (String s : wxUserSet) {
                        toUser += s + "|";
                    }
                    toUser = toUser.substring(0, toUser.length() - 1);
                    String content = "盘点计划[" + plan.getTitle() + "]，请按照盘点周期进行盘点";
                    String msg = weiXinService.setWxUserTextMessage(toUser, content);
                    if(!StrUtil.isEmpty(msg)){
                        throw new ServiceException(msg);
                    }
                }
            }catch (Exception e){
                logger.error(e.getMessage());
            }
        }
    }
}
